package com.qianwei.footpath.ui;

import static com.qianwei.footpath.utils.Util.calculateProgress;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.common.baselib.mvp.MvpBasePresenter;
import com.common.baselib.string.GsonUtil;
import com.common.baselib.ui.ToastUtil;
import com.qianwei.footpath.R;
import com.qianwei.footpath.base.BaseActivity;
import com.qianwei.footpath.bean.BodyCompositionData;
import com.qianwei.footpath.event.SerialPortEvent;
import com.qianwei.footpath.manage.DataManager;
import com.qianwei.footpath.manage.LocalCacheDataManage;
import com.qianwei.footpath.manage.SerialPortManager;
import com.qianwei.footpath.manage.TimerManager;
import com.qianwei.footpath.utils.TextToSpeechUtils;
import com.qianwei.footpath.utils.Util;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.TimerTask;

public class TestB extends BaseActivity {
    private static final String TAG = "Test---";
    private static final int HEART_MIN_VALUE = 40;
    private static final int HEART_MAX_VALUE = 230;
    private ImageView ivXuHua, ivRen;
    private TextView ivTitle, tv_result, tvDown;
    private TextView tv_bodyFatRate, tv_bodyWaterRate, tv_muscleMass, tv_fatFreeWeight, tv_basalMetabolism,
            tv_protein, tv_inorganicSalt, tv_intracellularFluid, tv_extracellularFluid;
    private TextView tv_bodyFatRate_result, tv_bodyWaterRate_result, tv_muscleMass_result, tv_fatFreeWeight_result, tv_basalMetabolism_result,
            tv_protein_result, tv_inorganicSalt_result, tv_intracellularFluid_result, tv_extracellularFluid_result;
    private TextToSpeechUtils ttsUtils;
    private int testDownLoadTime = 30;
    private TimerTask testHeartRateTimeTask, testHandTimeTask;
    private TextView tvHeart;
    private SeekBar sbHeart;
    private int handRetryCount = 0;
    @Override
    protected int layoutId() {
        return R.layout.b_activity;
    }

    @Override
    protected void initData(Bundle savedInstanceState) {
        EventBus.getDefault().register(this);
        tv_bodyFatRate = findViewById(R.id.tv_bodyFatRate);
        tv_bodyWaterRate = findViewById(R.id.tv_bodyWaterRate);
        tv_muscleMass = findViewById(R.id.tv_muscleMass);
        tv_fatFreeWeight = findViewById(R.id.tv_fatFreeWeight);
        tv_basalMetabolism = findViewById(R.id.tv_basalMetabolism);
        tv_protein = findViewById(R.id.tv_protein);
        tv_inorganicSalt = findViewById(R.id.tv_inorganicSalt);
        tv_intracellularFluid = findViewById(R.id.tv_intracellularFluid);
        tv_extracellularFluid = findViewById(R.id.tv_extracellularFluid);

        tv_bodyFatRate_result = findViewById(R.id.tv_bodyFatRate_result);
        tv_bodyWaterRate_result = findViewById(R.id.tv_bodyWaterRate_result);
        tv_muscleMass_result = findViewById(R.id.tv_muscleMass_result);
        tv_fatFreeWeight_result = findViewById(R.id.tv_fatFreeWeight_result);
        tv_basalMetabolism_result = findViewById(R.id.tv_basalMetabolism_result);
        tv_protein_result = findViewById(R.id.tv_protein_result);
        tv_inorganicSalt_result = findViewById(R.id.tv_inorganicSalt_result);
        tv_intracellularFluid_result = findViewById(R.id.tv_intracellularFluid_result);
        tv_extracellularFluid_result = findViewById(R.id.tv_extracellularFluid_result);

        tvHeart = findViewById(R.id.tvHeart);
        ivTitle = findViewById(R.id.ivTitle);
        ivXuHua = findViewById(R.id.ivXuHua);
        tvDown = findViewById(R.id.tvDown);
        tv_result = findViewById(R.id.tv_result);
        ivRen = findViewById(R.id.ivRen);
        sbHeart = findViewById(R.id.sbHeart);

        ivRen.setImageResource(R.drawable.ic_ren2);
        ivTitle.setText("心率测量");
        tv_result.setText("即将为您测量心率\n" +
                "请紧握脂肪把手！");

        testDownLoadTime = LocalCacheDataManage.getLocalConfigData().getPhysical_test_timeout();

        sbHeart.setOnTouchListener((v, e) -> true);

        startZoomAnimation();

        initTTS();
    }

    private void initTTS() {
        ttsUtils = new TextToSpeechUtils(this, new TextToSpeechUtils.OnInitListener() {
            @Override
            public void onInitSuccess() {
                speak("即将为您测量心率，请双手紧握把手", "101");
                Log.e(TAG, "发送心率指令");
                SerialPortManager.getInstance(getContext()).sendHeartRateCommand();
                stopTimeTask(testHeartRateTimeTask);
                startTestHeartRateTimeTask();
            }

            @Override
            public void onInitFailed(int errorCode) {
                Log.e(TAG, "TTS初始化失败");
                showToast("语音播报初始化失败");
                Log.e(TAG, "发送心率指令");
                SerialPortManager.getInstance(getContext()).sendHeartRateCommand();
                stopTimeTask(testHeartRateTimeTask);
                startTestHeartRateTimeTask();
            }
        });

    }

    private void speak(String text, String utteranceId) {
        ttsUtils.speak(text, utteranceId, null);
    }

    private void startZoomAnimation() {
        ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(ivXuHua, "scaleX", 1f, 1.1f);
        ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(ivXuHua, "scaleY", 1f, 1.1f);
        scaleXAnimator.setDuration(800);
        scaleYAnimator.setDuration(800);
        scaleXAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        scaleYAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        scaleXAnimator.setRepeatCount(ValueAnimator.INFINITE);
        scaleYAnimator.setRepeatCount(ValueAnimator.INFINITE);
        scaleXAnimator.setRepeatMode(ValueAnimator.REVERSE);
        scaleYAnimator.setRepeatMode(ValueAnimator.REVERSE);

        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
        animatorSet.start();
    }

    private void startTestHeartRateTimeTask() {
        if (testHeartRateTimeTask == null) {
            Log.e(TAG, "心率定时器");
            testHeartRateTimeTask = new TimerTask() {
                private int secondsPassed = 0;

                @Override
                public void run() {
                    secondsPassed++;
                    runOnUiThread(() -> {
                        int dif = testDownLoadTime - secondsPassed;
                        tvDown.setText(dif + "s");
                    });
                    if (secondsPassed >= testDownLoadTime) {
                        finish();
                    }
                }
            };
            TimerManager.getInstance().startTimer(1000, 1000, testHeartRateTimeTask);
        }
    }

    private void startTestHandTimeTask() {
        if (testHandTimeTask == null) {
            Log.e(TAG, "双手定时器");
            testHandTimeTask = new TimerTask() {
                private int secondsPassed = 0;

                @Override
                public void run() {
                    secondsPassed++;
                    runOnUiThread(() -> {
                        int dif = testDownLoadTime - secondsPassed;
                        tvDown.setText(dif + "s");
                    });
                    if (secondsPassed >= testDownLoadTime) {
                        finish();
                    }
                }
            };
            TimerManager.getInstance().startTimer(1000, 1000, testHandTimeTask);
        }
    }

    private void stopTimeTask(TimerTask timerTask) {
        if (timerTask != null) {
            TimerManager.getInstance().stopTimer(timerTask);
            timerTask.cancel();
        }
    }

    private void showToast(String message) {
        runOnUiThread(() -> Toast.makeText(this, message, Toast.LENGTH_SHORT).show());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onHeartRateCompletion(SerialPortEvent.HeartRateCompletionEvent event) {
        int finalValue = event.finalValue;
        Log.e(TAG, "心率完成: " + finalValue);
        stopTimeTask(testHeartRateTimeTask);

        int heartRateResultValue = finalValue;
        tvHeart.setText(String.valueOf(heartRateResultValue));
        int heartProgress = calculateProgress(heartRateResultValue, HEART_MIN_VALUE, HEART_MAX_VALUE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            sbHeart.setProgress(heartProgress, true);
        } else {
            sbHeart.setProgress(heartProgress);
        }

        DataManager.getInstance().setHeartRateResultValue(heartRateResultValue);

        speak("请您双手紧握把手，开始身体成分测量", "Hand");
        Log.e(TAG, "发送双手成分指令");
        double heightResultValue = DataManager.getInstance().getHeightResultValue();
        double weightResultValue = DataManager.getInstance().getWeightResultValue();
        int age = DataManager.getInstance().getAge();
        int sex = DataManager.getInstance().getSex();
        SerialPortManager.getInstance(getContext())
                .sendHandMeasureCommand(sex == 1 ? 'M' : 'W', age, (int) heightResultValue * 10, (float) Util.roundToOneDecimal(weightResultValue));

        stopTimeTask(testHandTimeTask);
        startTestHandTimeTask();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onHandCompletion(SerialPortEvent.HandCompletionEvent event) {
        BodyCompositionData data = event.data;
        if (data == null || !data.getUnsetFields().isEmpty()) {
            Log.e(TAG, "成分有返回空数据: " + data);
            if (handRetryCount >= 5) {
                Log.e(TAG, "成分测量超次数了");
                finish();
                return;
            }
            new Handler(Looper.getMainLooper()).postDelayed(() -> {
                speak("请您双手紧握把手，正在身体成分测量", "Hand");
                Log.e(TAG, "发送双手成分指令");
                double heightResultValue = DataManager.getInstance().getHeightResultValue();
                double weightResultValue = DataManager.getInstance().getWeightResultValue();
                int age = DataManager.getInstance().getAge();
                int sex = DataManager.getInstance().getSex();
                SerialPortManager.getInstance(getContext())
                        .sendHandMeasureCommand(sex == 1 ? 'M' : 'W', age, (int) heightResultValue * 10, (float) Util.roundToOneDecimal(weightResultValue));

                stopTimeTask(testHandTimeTask);
                testHandTimeTask = null;
                startTestHandTimeTask();
            }, 500);

            handRetryCount++;
            return;
        }

        stopTimeTask(testHandTimeTask);
        testHandTimeTask = null;
        if (data != null) {
            tv_bodyFatRate.setText(String.format("%.1f%%", data.getBodyFatRate()));
            tv_bodyFatRate_result.setText(Util.getBodyFatRateCategory(data.getBodyFatRate()));

            tv_bodyWaterRate.setText(String.format("%.1f%%", data.getBodyWaterRate()));
            tv_bodyWaterRate_result.setText(Util.getBodyWaterRateCategory(data.getBodyWaterRate()));

            tv_protein.setText(String.format("%.1fkg", data.getProtein()));
            tv_protein_result.setText(Util.getProteinCategory(data.getProtein()));

            tv_intracellularFluid.setText(String.format("%.1fL", data.getIntracellularFluid()));
            tv_intracellularFluid_result.setText(Util.getIntracellularFluidCategory(data.getIntracellularFluid()));

            tv_extracellularFluid.setText(String.format("%.1fL", data.getExtracellularFluid()));
            tv_extracellularFluid_result.setText(Util.getExtracellularFluidCategory(data.getExtracellularFluid()));

            tv_muscleMass.setText(String.format("%.1fkg", data.getMuscleMass()));
            tv_muscleMass_result.setText(Util.getMuscleMassCategory(data.getMuscleMass()));

            tv_basalMetabolism.setText(String.format("%dkcal", data.getBasalMetabolism()));
            tv_basalMetabolism_result.setText(Util.getBasalMetabolismCategory(data.getBasalMetabolism()));

            tv_fatFreeWeight.setText(String.format("%.1fkg", data.getFatFreeWeight()));
            tv_fatFreeWeight_result.setText(Util.getFatFreeWeightCategory(data.getFatFreeWeight()));

            tv_inorganicSalt.setText(String.format("%.1fkg", data.getInorganicSalt()));
            tv_inorganicSalt_result.setText(Util.getInorganicSaltCategory(data.getInorganicSalt()));
        }

        DataManager.getInstance().setBodyCompositionData(data);

        new Handler().postDelayed(() -> {
            startActivity(new Intent(getContext(), TestC.class));
            finish();
        }, 1000);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onError(SerialPortEvent.ErrorEvent event) {
        ToastUtil.showToastLong(getContext(), "报错：" + event.message);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onProtocolError(SerialPortEvent.ProtocolErrorEvent event) {
        ToastUtil.showToastLong(getContext(), "报错：errorCode=" + event.errorCode + ",errorMsg=" + event.errorMsg);
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        if (ttsUtils != null) {
            ttsUtils.release();
            ttsUtils = null;
        }
        stopTimeTask(testHandTimeTask);
        stopTimeTask(testHeartRateTimeTask);
        super.onDestroy();
    }

    @Override
    protected MvpBasePresenter createPresenter() {
        return null;
    }
}
